import React, { useEffect, useState, useRef } from 'react';
import { useDispatch, useSelector } from 'umi';
// import _ from 'lodash';
import styles from './index.less';
import { useEffectOnce } from 'react-use';
import { ConnectProps, ConnectState } from '@/models/connect';
import ColorPicker from '@/components/widgets/ColorPicker';
import { Button, Select, InputNumber, Space, Switch, message } from 'antd';
import { jsapi, viewUtils } from '@/utils/arcgis';
import _cloneDeep from 'lodash/cloneDeep';

// import { hydratGraphicLayer, exhydratGraphicLayer } from './localStore';
import { hydratGraphicLayer, exhydratGraphicLayer } from './onlineStore';
import FlowMode from './flowMode';

const { Option } = Select;
export interface ElementRenderProps {}
interface ConnectedProps extends ConnectProps {
  // isFullScreen: boolean;
  // isGlobalProcessRender: boolean;
  // dispatch: Dispatch;
}

function transRGBAToArr(rgbaStr) {
  var matchs = rgbaStr.match(/^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/);
  return matchs.slice(1).map(n => +n);
}

// 绘制选择数据
const DRAW_SELECT_DATA: { title: string; value: 'point' | 'polyline' | 'polygon' }[] = [
  { title: '兴趣点', value: 'point' },
  { title: '线段', value: 'polyline' },
  { title: '多边形', value: 'polygon' },
];

//数据选项
const DATA_SELECT = {
  polyline: {
    style: [
      { key: 'wall', title: '围墙' },
      { key: 'square-tube', title: '方管' },
      { key: 'round-tube', title: '圆管' },
      { key: 'strip', title: '条带' },
      { key: 'flow', title: '流光线' },
    ],
    cap: [
      { key: 'round', title: '圆形线帽' },
      { key: 'butt', title: '无线帽' },
      { key: 'square', title: '矩形线帽' },
      { key: 'none', title: '无封口' },
    ],
    join: [
      { key: 'miter', title: '斜接' },
      { key: 'round', title: '圆角' },
      { key: 'bevel', title: '斜角' },
    ],
  },
  point: {
    primitive: [
      { key: 'circle', title: '圆形' },
      { key: 'square', title: '方形' },
      { key: 'cross', title: '十字' },
      { key: 'x', title: 'x' },
      { key: 'kite', title: '菱形' },
      { key: 'triangle	', title: '三角形' },
    ],
  },
};

// 保存每一次方案的几乎图形
let schemeList: any = [];

// 要素渲染绘制图层渲染
export const ELEMENT_RENDERLAYER_ID = 'sketchLayer';

const ElementRender: React.FC<ElementRenderProps & ConnectedProps> = () => {
  const dispatch = useDispatch();
  const schemeData = useSelector(store => store.scheme.schemeData) || {};
  let schemeIndex = Object.keys(schemeData).length + 1;
  const [drawSelect, setDrawSelect] = useState<'point' | 'polygon' | 'circle' | 'polyline'>(
    'point',
  );
  // sketch操作模型
  const [sketchViewModel, setSketchViewModel] = useState<null | __esri.SketchViewModel>(null);

  // 折线绘制选择
  const [lineStyleOptions, setLineStyleOptions] = useState({
    profile: 'quad',
    cap: 'round',
    join: 'miter',
    width: 5,
    height: 30,
    color: 'rgba(81,220,233,1)',
    profileRotation: 'all',
  });

  // 点绘制选择
  const [pointStyleOptions, setPointStyleOptions] = useState({
    outlineColor: 'rgba(255,255,255,1)',
    outlineSize: 2,
    size: 16,
    color: 'rgba(81,220,233,1)',
    primitive: 'circle',
  });

  // 面绘制选择
  const [polygonStyleOptions, setPolygonStyleOptions] = useState({
    edgesColor: 'rgba(255,255,255,1)',
    edgesSize: 2,
    size: 16,
    color: 'rgba(81,220,233,1)',
    // color: 'rgba(81,220,233,1)',
  });

  const [drawActive, setDrawActive] = useState<boolean>(false);

  const [isRenderFlow, setIsRenderFlow] = useState<boolean>(false);
  const attrRef = useRef<any>(null);
  const [isInit, setIsInit] = useState(false);

  useEffect(() => {
    finishDraw('cancel');
    return () => {
      // clearAll();
    };
  }, [drawSelect]);

  useEffectOnce(() => {
    let searchParams = new URLSearchParams(window.location.href);
    initialize(searchParams.get('i'));
  });

  useEffect(() => {
    let type = '';
    switch (drawSelect) {
      case 'point':
        type = pointStyleOptions.primitive;
        break;
      case 'polyline':
        type = 'wall';
        break;
      case 'polygon':
        type = 'polygon';
        break;
      default:
        break;
    }
    attrRef.current = { type };
  }, [pointStyleOptions, drawSelect]);

  // 获取点Symbol样式
  function getPointSymbol() {
    return {
      type: 'point-3d',
      symbolLayers: [
        {
          type: 'icon', // autocasts as new IconSymbol3DLayer()
          size: pointStyleOptions.size, // points
          resource: { primitive: pointStyleOptions.primitive },
          material: { color: transRGBAToArr(pointStyleOptions.color) },
          outline: {
            color: transRGBAToArr(pointStyleOptions.outlineColor),
            size: pointStyleOptions.outlineSize,
          },
        },
      ],
    };
  }
  // 获取折线Symbol样式
  function getPolylineSymbol() {
    return {
      type: 'line-3d',
      symbolLayers: [
        {
          type: 'path',
          profile: lineStyleOptions.profile,
          material: {
            color: transRGBAToArr(lineStyleOptions.color),
          },
          width: lineStyleOptions.width,
          height: lineStyleOptions.height,
          join: lineStyleOptions.join,
          cap: lineStyleOptions.cap,
          anchor: 'bottom',
          profileRotation: lineStyleOptions.profileRotation,
        },
      ],
    };
  }
  // 获取面Symbol样式
  function getPolygonSymbol() {
    return {
      type: 'polygon-3d',
      symbolLayers: [
        {
          type: 'extrude',
          size: polygonStyleOptions.size, // extrude by 10 meters
          material: {
            color: transRGBAToArr(polygonStyleOptions.color),
          },
          edges: {
            type: 'solid',
            size: `${polygonStyleOptions.edgesSize}px`,
            color: transRGBAToArr(polygonStyleOptions.edgesColor),
          },
        },
      ],
    };
  }
  function changeGraphicColor(graphic) {
    const fillSymbol3DLayer = graphic.symbol.symbolLayers.getItemAt(0); // 获取第一个 Symbol3DLayer
    switch (graphic.particulars.schedule) {
      case 'noStart':
        fillSymbol3DLayer.material.color = [242, 244, 247];
        break;
      case 'underway':
        fillSymbol3DLayer.material.color = [165, 251, 63];
        break;
      case 'fulfill':
        fillSymbol3DLayer.material.color = [81, 220, 233];
        break;
      default:
        break;
    }

    graphic.symbol = graphic.symbol.clone(); // 更新符号
  }

  // 组件初始化
  async function initialize(projectId) {
    const view = await viewUtils.isViewReady();
    console.log('view', view);
    let sketchLayer = view.map.findLayerById(ELEMENT_RENDERLAYER_ID);
    const [GraphicsLayer, SketchViewModel] = await jsapi.load([
      'esri/layers/GraphicsLayer',
      'esri/widgets/Sketch/SketchViewModel',
    ]);
    if (!sketchLayer) {
      sketchLayer = new GraphicsLayer({
        id: ELEMENT_RENDERLAYER_ID,
        title: '要素渲染绘制图层',
        elevationInfo: { mode: 'on-the-ground' },
      });

      hydratGraphicLayer(sketchLayer, projectId);
      view.map.addMany([sketchLayer]);
    }

    // 使用SketchViewModel绘制用于查询的多边形
    const sketchViewModel_ = new SketchViewModel({
      layer: sketchLayer,
      defaultUpdateOptions: {
        tool: 'reshape',
        toggleToolOnClick: true,
        // toggleToolOnClick: false,
      },
      view: view,
      polylineSymbol: getPolylineSymbol(),
      pointSymbol: getPointSymbol(),
      polygonSymbol: getPolygonSymbol(),
    });
    //更新SketchViewModel创建更新时更新查询图多变形
    sketchViewModel_.on('create', function(event) {
      console.log('create被触发', event);
      if (event.state === 'complete' || event.state === 'cancel') {
        try {
          event.graphic.attributes = attrRef.current;
          console.log('graphic----------', attrRef);
          schemeList.push(event.graphic);
          setDrawActive(false);
        } catch (error) {
          setDrawActive(false);
        }
      }
    });
    sketchViewModel_.on('update', function(event) {
      console.log('update被触发', event.state);
      const graphic = event.graphics[0];
      if (event.state === 'complete' || event.state === 'cancel') {
        setDrawActive(false);
        // 关闭征拆详情弹框
        dispatch({
          type: 'scheme/updateIsVisibleGraph',
          payload: false,
        });
        graphic.particulars = JSON.parse(localStorage.getItem('particulars') || '{}');
        if (graphic.particulars.revamp) changeGraphicColor(graphic);
      }
      if (event.state === 'start') {
        setDrawActive(true);
        // 回显数据
        if (graphic.particulars && JSON.stringify(graphic.particulars) !== '{}') {
          localStorage.setItem('particulars', JSON.stringify(graphic.particulars));
        } else {
          localStorage.setItem(
            'particulars',
            JSON.stringify({
              name: '',
              schedule: 'noStart',
              explain: '',
              fileList: [],
              revamp: false,
            }),
          );
        }

        // 打开征拆详情弹框
        dispatch({
          type: 'scheme/updateIsVisibleGraph',
          payload: true,
        });
      }
      console.log('graphic--------------', graphic);
    });
    sketchViewModel_.on('delete', function(event) {
      console.log('delete被触发');
      const uid = event.graphics[0].uid;
      if (schemeList.length > 0) {
        schemeList = schemeList.filter(i => i.uid !== uid);
      }
      dispatch({
        type: 'scheme/delData',
        payload: {
          uid,
        },
      });
    });
    dispatch({
      type: 'scheme/updateSketchViewModel',
      payload: sketchViewModel_,
    });
    setSketchViewModel(sketchViewModel_);
    setIsInit(true);
  }

  // 开始绘制
  function startDraw() {
    if (sketchViewModel && drawSelect) {
      sketchViewModel.cancel();
      sketchViewModel.polylineSymbol = getPolylineSymbol() as any;
      sketchViewModel.pointSymbol = getPointSymbol() as any;
      sketchViewModel.polygonSymbol = getPolygonSymbol() as any;
      if (drawSelect === 'point') {
        sketchViewModel.defaultUpdateOptions = {
          tool: 'transform',
          toggleToolOnClick: true,
        };
      } else {
        sketchViewModel.defaultUpdateOptions = {
          tool: 'reshape',
          toggleToolOnClick: true,
        };
      }
      sketchViewModel.create(drawSelect);
      setDrawActive(true);
      return;
    }
    message.info('绘制区域初始化中，请稍后点击');
  }

  // 结束绘制
  function finishDraw(type: 'finish' | 'cancel') {
    if (sketchViewModel) {
      if (type === 'cancel') {
        sketchViewModel.cancel();
      } else {
        sketchViewModel.complete();
      }
    }
  }

  // 组件销毁
  async function clearAll() {
    if (sketchViewModel) {
      sketchViewModel.cancel();
    }
    const view = await viewUtils.isViewReady();
    const sketchLayer = view.map.findLayerById(ELEMENT_RENDERLAYER_ID);
    if (sketchLayer) {
      view.map.remove(sketchLayer);
    }
  }

  // 渲染选项
  function renderOptions(data) {
    return data.map(item => {
      return (
        <Option key={item.key} value={item.key}>
          {item.title}
        </Option>
      );
    });
  }

  // 更新绘制线样式
  function updateLineStyle(key: string, value: any) {
    const lineStyleOptions_ = JSON.parse(JSON.stringify(lineStyleOptions));
    if (key === 'style') {
      attrRef.current = { type: value };
      switch (value) {
        case 'round-tube':
          lineStyleOptions_.profile = 'circle';
          lineStyleOptions_.height = 30;
          lineStyleOptions_.width = 30;
          break;
        case 'square-tube':
          lineStyleOptions_.profile = 'quad';
          lineStyleOptions_.height = 30;
          lineStyleOptions_.width = 30;
          break;
        case 'wall':
          lineStyleOptions_.profile = 'quad';
          lineStyleOptions_.height = 30;
          lineStyleOptions_.width = 5;
          break;
        case 'strip':
          lineStyleOptions_.profile = 'quad';
          lineStyleOptions_.height = 5;
          lineStyleOptions_.width = 30;
          break;
        case 'flow':
          lineStyleOptions_.profile = 'quad';
          lineStyleOptions_.height = 1;
          lineStyleOptions_.width = 1;
          break;
      }
    } else {
      lineStyleOptions_[key] = value;
    }

    setLineStyleOptions(lineStyleOptions_);
  }

  // 更新绘制线样式
  function updatePointStyle(key: string, value: string | number) {
    const pointStyleOptions_ = JSON.parse(JSON.stringify(pointStyleOptions));
    pointStyleOptions_[key] = value;
    setPointStyleOptions(pointStyleOptions_);
  }

  // 更新绘制面样式
  function updatePolygonStyle(key: string, value: string | number) {
    const polygonStyleOptions_ = JSON.parse(JSON.stringify(polygonStyleOptions));
    polygonStyleOptions_[key] = value;
    setPolygonStyleOptions(polygonStyleOptions_);
  }

  // 渲染用户输入选项
  function renderUserInput() {
    switch (drawSelect) {
      case 'polyline':
        return (
          <div className={styles.inputWrap}>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>颜色:</div>
              <div className={styles.itemInput} style={{ color: '#333' }}>
                <ColorPicker
                  small={false}
                  color={lineStyleOptions.color}
                  onChange={color => {
                    updateLineStyle('color', color);
                  }}
                  disabled={drawActive}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>线样式:</div>
              <div className={styles.itemInput}>
                <Select
                  defaultValue={DATA_SELECT.polyline.style[0].key}
                  style={{ width: '100%' }}
                  disabled={drawActive}
                  onChange={data => {
                    updateLineStyle('style', data);
                  }}
                >
                  {renderOptions(DATA_SELECT.polyline.style)}
                </Select>
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>线端口:</div>
              <div className={styles.itemInput}>
                <Select
                  defaultValue={DATA_SELECT.polyline.cap[0].key}
                  style={{ width: '100%' }}
                  disabled={drawActive}
                  onChange={data => {
                    updateLineStyle('cap', data);
                  }}
                >
                  {renderOptions(DATA_SELECT.polyline.cap)}
                </Select>
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>线连接:</div>
              <div className={styles.itemInput}>
                <Select
                  defaultValue={DATA_SELECT.polyline.join[0].key}
                  style={{ width: '100%' }}
                  disabled={drawActive}
                  onChange={data => {
                    updateLineStyle('join', data);
                  }}
                >
                  {renderOptions(DATA_SELECT.polyline.join)}
                </Select>
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>线宽度:</div>
              <div
                className={styles.itemInput}
                // key={lineStyleOptions.profile}
              >
                <InputNumber
                  min={0}
                  max={1000}
                  value={lineStyleOptions.width}
                  onChange={data => {
                    updateLineStyle('width', data);
                  }}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>线高度:</div>
              <div
                className={styles.itemInput}
                // key={lineStyleOptions.profile}
              >
                <InputNumber
                  min={0}
                  max={1000}
                  value={lineStyleOptions.height}
                  onChange={data => {
                    updateLineStyle('height', data);
                  }}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>流光:</div>
              <div
                className={styles.itemInput}
                // key={lineStyleOptions.profile}
              >
                <Switch checked={isRenderFlow} onChange={() => setIsRenderFlow(e => !e)} />
              </div>
            </div>
          </div>
        );
      case 'point':
        return (
          <div className={styles.inputWrap}>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>点样式</div>
              <div className={styles.itemInput}>
                <Select
                  defaultValue={pointStyleOptions.primitive}
                  style={{ width: '100%' }}
                  disabled={drawActive}
                  onChange={data => {
                    updatePointStyle('primitive', data);
                  }}
                >
                  {renderOptions(DATA_SELECT.point.primitive)}
                </Select>
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>颜色:</div>
              <div className={styles.itemInput} style={{ color: '#333' }}>
                <ColorPicker
                  small={false}
                  color={pointStyleOptions.color}
                  onChange={color => {
                    updatePointStyle('color', color);
                  }}
                  disabled={drawActive}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>大小:</div>
              <div className={styles.itemInput}>
                <InputNumber
                  min={0}
                  max={50}
                  defaultValue={pointStyleOptions.size}
                  onChange={data => {
                    updatePointStyle('size', data);
                  }}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>边框颜色</div>
              <div className={styles.itemInput} style={{ color: '#333' }}>
                <ColorPicker
                  small={false}
                  color={pointStyleOptions.outlineColor}
                  onChange={color => {
                    updatePointStyle('outlineColor', color);
                  }}
                  disabled={drawActive}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>边框线宽</div>
              <div className={styles.itemInput}>
                <InputNumber
                  min={0}
                  max={50}
                  defaultValue={pointStyleOptions.outlineSize}
                  onChange={data => {
                    updatePointStyle('outlineSize', data);
                  }}
                />
              </div>
            </div>
          </div>
        );
      case 'polygon':
        return (
          <div className={styles.inputWrap}>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>颜色:</div>
              <div className={styles.itemInput} style={{ color: '#333' }}>
                <ColorPicker
                  small={false}
                  color={polygonStyleOptions.color}
                  onChange={color => {
                    updatePolygonStyle('color', color);
                  }}
                  disabled={drawActive}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>高度:</div>
              <div className={styles.itemInput}>
                <InputNumber
                  min={0}
                  max={10000}
                  defaultValue={polygonStyleOptions.size}
                  onChange={data => {
                    updatePolygonStyle('size', data);
                  }}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>边框颜色</div>
              <div className={styles.itemInput} style={{ color: '#333' }}>
                <ColorPicker
                  small={false}
                  color={polygonStyleOptions.edgesColor}
                  onChange={color => {
                    updatePolygonStyle('edgesColor', color);
                  }}
                  disabled={drawActive}
                />
              </div>
            </div>
            <div className={styles.inputWrapItem}>
              <div className={styles.itemKey}>边框线宽</div>
              <div className={styles.itemInput}>
                <InputNumber
                  min={0}
                  max={50}
                  defaultValue={polygonStyleOptions.edgesSize}
                  onChange={data => {
                    updatePolygonStyle('edgesSize', data);
                  }}
                />
              </div>
            </div>
          </div>
        );

      default:
        break;
    }
  }

  async function saveGraphics(layerId) {
    let searchParams = new URLSearchParams(window.location.href);
    dispatch({
      type: 'scheme/addData',
      payload: {
        schemeList,
      },
    });
    schemeList = [];
    await exhydratGraphicLayer(layerId, searchParams.get('i'), schemeIndex);
    message.info('绘制保存成功');
  }

  return (
    <>
      <div className={styles.elementRender} style={{ position: 'absolute', top: 144, right: 88 }}>
        <div className="side-panel2" style={{ position: 'relative', top: 0, left: 0 }}>
          <div className="side-panel2-title">要素绘制</div>
          <div className="side-panel2-body" style={{ padding: 16 }}>
            <div className={styles.drawBtnWrap}>
              {DRAW_SELECT_DATA.map(item => {
                return (
                  <div
                    key={item.value}
                    className={`${styles.drawBtn} ${
                      item.value === drawSelect ? styles.drawBtnActive : null
                    }`}
                    onClick={() => {
                      setDrawSelect(item.value);
                    }}
                  >
                    {item.title}
                  </div>
                );
              })}
            </div>
            {drawSelect && (
              <React.Fragment>
                <div className={styles.textKey}>在地图场景中连续采集点，双击完成绘制点。</div>
                {renderUserInput()}
                <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                  {drawActive ? (
                    <Button
                      type={'primary'}
                      className={'c-btn2'}
                      onClick={() => {
                        finishDraw('cancel');
                      }}
                    >
                      取消
                    </Button>
                  ) : (
                    <Button className={'c-btn2'} type={'primary'} onClick={startDraw}>
                      开始
                    </Button>
                  )}
                  <Button className={'c-btn1'} onClick={() => saveGraphics(ELEMENT_RENDERLAYER_ID)}>
                    保存
                  </Button>
                </div>
              </React.Fragment>
            )}
          </div>
        </div>
      </div>
      {isInit && <FlowMode isRenderFlow={isRenderFlow} layerId={ELEMENT_RENDERLAYER_ID} />}
    </>
  );
};

export default ElementRender;
